#include "AudioMixer.h"

#define PCM1_FRAME_SIZE (2048)
#define PCM2_FRAME_SIZE (4096)
#define PCM_OUT_FRAME_SIZE (40000)

int main(int argc, char *argv[])
{
    if (argc < 3) {
        printf("usage: input1.pcm intput2.pcm output.pcm\n");
        return -1;
    }

    AudioMixer amix;
    //输入流
    amix.addAudioInput(0, 48000, 2, 32, AV_SAMPLE_FMT_FLT); // 48000_2_f32le.pcm
    amix.addAudioInput(1, 48000, 2, 16, AV_SAMPLE_FMT_S16); // 48000_2_s16le.pcm
    amix.addAudioInput(2, 48000, 2, 16, AV_SAMPLE_FMT_S16); // 48000_2_s16le.pcm

    //输出流
    amix.addAudioOutput(44100, 2, 16, AV_SAMPLE_FMT_S16);

    //init 之前，先添加输入源和输出源
    if (amix.init("shortest") < 0)
        return -1;

    int len1 = 0, len2 = 0, len3 = 0;
    uint8_t buf1[PCM1_FRAME_SIZE];
    uint8_t buf2[PCM2_FRAME_SIZE];
    uint8_t buf3[PCM2_FRAME_SIZE];
    FILE *file1 = fopen(argv[1], "rb");
    if (file1 == nullptr) {
        printf("fopen %s failed.\n", argv[1]);
        return -1;
    }

    FILE *file2 = fopen(argv[2], "rb");
    if (file2 == nullptr) {
        printf("fopen %s failed.\n", argv[2]);
        return -1;
    }

    FILE *file3 = fopen("yanguichao_48000_2_s16le_8s.pcm", "rb");
    if (file2 == nullptr) {
        printf("fopen yanguichao_48000_2_s16le_8s.pcm failed.\n");
        return -1;
    }

    FILE *file_out = fopen(argv[3], "wb");
    if (file_out == nullptr) {
        printf("fopen %s failed.\n", argv[3]);
        return -1;
    }

    uint8_t out_buf[PCM_OUT_FRAME_SIZE];
    uint32_t out_size = 0;

    int file1_finish = 0;
    int file2_finish = 0;
    int file3_finish = 0;

    while (1) {
        len1 = fread(buf1, 1, PCM1_FRAME_SIZE, file1);
        len2 = fread(buf2, 1, PCM2_FRAME_SIZE, file2);
        len3 = fread(buf3, 1, PCM2_FRAME_SIZE, file3);

        if (len1 > 0 || len2 > 0 || len3 > 0) {
            if (len1 > 0) {
                if (amix.addFrame(0, buf1, len1) < 0) {
                    printf("amix.addFrame(0, buf1, len1) failed.\n");
                    break;
                }
            }
            else {
                if (file1_finish == 0) {
                    file1_finish = 1;
                    if (amix.addFrame(0, NULL, 0) < 0) { //空包冲刷，才知道某一路没数据了
                        printf("amix.addFrame(0, buf1, len1) failed.\n");
                    }
                }
            }

            if (len2 > 0) {
                if (amix.addFrame(1, buf2, len2) < 0) {
                    printf("amix.addFrame(1, buf2, len2) faile.d\n");
                    break;
                }
            }
            else {
                if (file2_finish == 0) {
                    file2_finish = 1;
                    if (amix.addFrame(1, NULL, 0) < 0) {
                        printf("amix.addFrame(1, buf2, len2) failed.\n");
                    }
                }
            }

            if (len3 > 0) {
                if (amix.addFrame(2, buf3, len3) < 0) {
                    printf("amix.addFrame(0, buf3, len3) failed.\n");
                    break;
                }
            }
            else {
                if (file3_finish == 0) {
                    file3_finish = 1;
                    if (amix.addFrame(2, NULL, 0) < 0) { //空包冲刷，才知道某一路没数据了
                        printf("amix.addFrame(0, buf3, len3) failed.\n");
                    }
                }
            }

            int ret = 0; //amix.getFrame(out_buf, 10240);

            while ((ret = amix.getFrame(out_buf, 10240)) >= 0) {
                out_size += ret;
                if (out_size % (1024*1024) == 0) {
                    printf("mix audio: %d, out_size: %u\n", ret, out_size);
                }
                fwrite(out_buf, 1, ret, file_out);
            }
        }
        else {
            printf("two file finish.\n");
            break;
        }
    }

    printf("end, out_size:%u\n", out_size);
    amix.exit();

    if (file_out != nullptr)
        fclose(file_out);

    if (file1 != nullptr)
        fclose(file1);

    if (file2 != nullptr)
        fclose(file2);

    if (file3 != nullptr)
        fclose(file3);

    getchar();

    return 0;
}
